#ifndef PERCEPTION_DEFS_H_
#define PERCEPTION_DEFS_H_
#include <Eigen/Core>
#include <memory>
#include <vector>

#include "basic_settings.h"
#include "basic_type.h"
#include "circular_queue.h"
#include "fixed_array.h"
#include "map_info.h"
#include "point_cloud.h"
#include "point_type.h"
#include "postprocess/common/firstorderlowpassfilter.h"

///@brief max Bounding box number
constexpr std::uint32_t kMaxBoundingBoxNum{4096U};
///@brief max Tracking box number
constexpr std::uint32_t kMaxTrackerObjectNum{1024U};

/// @brief bounding box
struct BoundingBox {
  uint8_t id;
  autodrive::perception::Point3f center;
  float length;
  float width;
  float height;
  float heading;
  float r;
  float score;
  std::uint16_t label;
  autodrive::perception::fixed_array<autodrive::perception::Point2f, 4> polygon;
  float vx;
  float vy;
  float ax;
  float ay;
  float scores[10];
};

enum class ProcessorClass { Vehicle, Pedestrian, StaticBarrier };

struct TrackedObject {
  uint16_t id;
  Eigen::Vector3f center;
  Eigen::Vector3f size;
  float heading;
  float r;
  float score;
  float scores[10];
  std::uint16_t label;
  autodrive::perception::fixed_array<autodrive::perception::Point2f, 4> polygon;
  Eigen::Vector3f velocity;
  Eigen::Vector3f acceleration;
  /// @brief association score
  float association_score = 0.0f;
  std::uint64_t timestamp;
  ProcessorClass processor_flag;
  /// @brief first order filter for heading
  FirstOrderLowPassFilter<Eigen::Vector3f> heading_filter;
};

struct Obstacle {
  uint16_t id;
  Eigen::Vector3f center;
  Eigen::Vector3f size;
  float heading;
  Eigen::Vector3f velocity;
  Eigen::Vector3f acceleration;
  std::uint16_t label;
};

namespace autodrive {
namespace perception {

///@brief max Bounding box number
constexpr std::uint32_t kMaxPerceptionResultNum{8U};

struct PerceptionResult {
  /// @brief timestamp
  std::uint64_t timestamp;
  /// @brief deeplearning BoundingBox list
  fixed_array<BoundingBox, kMaxBoundingBoxNum> dl_boxes;
  /// @brief tracker objects list
  fixed_array<TrackedObject, kMaxTrackerObjectNum> tracker_objects;
  /// @brief output obstacles
  fixed_array<Obstacle, kMaxBoundingBoxNum> output_objects;
  /// @brief map
  Map map;
  /// @brief  rtk data buffer ptr
  RTKDataBufferPtr rtk_data_buffer_ptr;
  /// @brief microseconds
  std::uint64_t total_run_time;
  /// @brief imagesource pointer
  ImageSourcePtr<float> image_source_ptr;
  /// @brief pointcloud source pointer
  PointCloudSourcePtr pcl_source_ptr;
  /// @brief calib data set pointer
  CalibDataSetPtr calib_data_set_ptr;
};

using PerceptionResultBuffer =
    CircularQueue<PerceptionResult, kMaxPerceptionResultNum>;

using PerceptionResultBufferPtr = std::shared_ptr<PerceptionResultBuffer>;

}  // namespace perception
}  // namespace autodrive

#endif  // !PERCEPTION_DEFS_H_
